当DP遇见Py(六) -- 原型模式

目录
  1. 定义:
  2. 类图:
  3. 类型:创建型
  4. 实例:
    1. C++ 实现
    2. Python 实现
    3. 执行结果:
  5. Tips:

定义:

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

类图:

类型:创建型

实例:

从简历原型,生成新的简历。

C++ 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <string>
using namespace std;

class Resume
{
private:
string name,sex,age,timeArea,company;
public:
Resume(string s)
{
name=s;
}
void setPersonalInfo(string s,string a)
{

sex=s;
age=a;
}
void setWorkExperience(string t,string c)
{

timeArea=t;
company=c;
}
void display()
{

cout<<name<<" "<<sex<<" "<<age<<endl;
cout<<"工作经历: "<<timeArea<<" "<<company<<endl<<endl;

}
Resume *clone()
{
Resume *b;
b=new Resume(name);
b->setPersonalInfo(sex,age);
b->setWorkExperience(timeArea,company);
return b;
}
};


int main()
{

Resume *a = new Resume("大鸟");
a->setPersonalInfo("男", "29");
a->setWorkExperience("1998-2000", "XX公司");

Resume *b = a->clone();
b->setWorkExperience("1998-2006", "YY企业");

Resume *c = a->clone();
c->setPersonalInfo("女", "24");

a->display();
b->display();
c->display();

return 0;
}

Python 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# -*- coding=utf-8 -*-

import copy

class Prototype:
def __init__(self):
self._objects = {}

def register_object(self, name, obj):
self._objects[name] = obj

def unregister_object(self, name):
del self._objects[name]

def clone(self, name, **attr):
obj = copy.deepcopy(self._objects[name])
obj.__dict__.update(attr)
return obj

class Resume:
def __init__(self, name):
self.name = name

def set_personal_info(self, sex, age):
self.sex = sex
self.age = age

def set_work_experience(self, time_area, company):
self.time_area = time_area
self.company = company

def __str__(self):
return '%s %s %s\n工作经历:%s %s' % (
self.name, self.sex, self.age,
self.time_area, self.company
)

if __name__ == '__main__':
a = Resume('大鸟')
a.set_personal_info('男', 29)
a.set_work_experience('1998-2000', 'XX公司')

prototype = Prototype()
prototype.register_object('resume', a)

b = prototype.clone('resume')
b.set_work_experience('1998-2006', 'YY企业')

c = prototype.clone('resume', sex='女', age=24)

print a
print b
print c

执行结果:

1
2
3
4
5
6
大鸟 男 29
工作经历:1998-2000 XX公司
大鸟 男 29
工作经历:1998-2006 YY企业
大鸟 女 24
工作经历:1998-2000 XX公司

Tips:

  • 以上的Python实现比C++提供了更丰富和完整的原型模式实现。使用Prototype类来管理原型,并提供统一的clone方法来生成新对象。
  • Python为对象提供的copy模块中的copy方法和deepcopy方法已经实现了原型模式。copy方法实现浅拷贝,deepcopy方法实现深拷贝。
  • __str__魔术方法。用来定义对象如何转换为字符串形式,被print所调用。关于Python魔术方法请见《当DP遇见Py(四) — 代理模式》中的介绍。
  • __dict__Python中的__dict__比较神奇,一两句话也说不清楚。简而言之,你可以把__dict__看做Python对象的属性字典(注:Python中一切皆对象,O(∩∩)O~)。Python的强大的动态能力,如:Python的对象可以在运行期动态添加定义时没有的属性,就是这货在提供支持。语句`obj._dict.update(attr)就是根据用户传入的attr来更新对象obj`的属性。

“克隆”是要给钱地!

评论